<template>
  <div class="jcx-code-editor" :style="{ height: _height }">
    <textarea ref="textareaRef" v-model="contentValue"></textarea>
  </div>
</template>

<script setup>
import {computed, markRaw, onMounted, ref, watch} from "vue";
import {useGlobalStoreHook} from "@/store/global";
// 框架
import CodeMirror from "codemirror";
import "codemirror/lib/codemirror.css";
// 主题
import "codemirror/theme/idea.css";
import "codemirror/theme/darcula.css";
// 功能
import "codemirror/addon/selection/active-line";
import "codemirror/addon/display/autorefresh";
// 语言
import "codemirror/mode/javascript/javascript";
import "codemirror/mode/sql/sql";
import "codemirror/mode/vue/vue";
import "codemirror/mode/xml/xml";

const props = defineProps({
  modelValue: {
    type: String,
    default: "",
  },
  mode: {
    type: String,
    default: "javascript",
  },
  height: {
    type: [String, Number],
    default: 300,
  },
  options: {
    type: Object,
    default: () => {
    },
  },
  theme: {
    type: String,
    default: computed(() => useGlobalStoreHook().getAppDark ? 'darcula' : "idea"),
  },
  readOnly: {
    type: Boolean,
    default: false,
  },
});
const emit = defineEmits(['update:modelValue']);
const contentValue = ref(props.modelValue);
const textareaRef = ref(null);
const coder = ref(null);
const opt = ref({
  // 自动刷新
  autoRefresh: true,
  // 主题
  theme: props.theme,
  // 高亮当前行
  styleActiveLine: true,
  // 行号
  lineNumbers: true,
  // 自动换行
  lineWrapping: false,
  // Tab缩进
  tabSize: 4,
  // 缩进单位
  indentUnit: 4,
  // 自动缩进
  indentWithTabs: true,
  // 语言
  mode: props.mode,
  // 只读
  readOnly: props.readOnly,
  ...props.options,
});
const _height = computed(() => Number(props.height) ? Number(props.height) + "px" : props.height);
const init = () => {
  coder.value = markRaw(CodeMirror.fromTextArea(textareaRef.value, opt.value));
  coder.value.on("change", (coder) => {
    contentValue.value = coder.getValue();
    emit("update:modelValue", contentValue.value);
  });
}
const formatStrInJson = (strValue) => {
  return JSON.stringify(JSON.parse(strValue), null, 4);
}

onMounted(() => {
  init();
  // 获取挂载的所有modes
  // console.log(CodeMirror.modes)
});

watch(() => props.modelValue, (val) => {
  contentValue.value = val;
  if (val !== coder.value.getValue()) {
    if (val === null) val = "";
    coder.value.setValue(val);
  }
});
</script>

<style scoped>
.jcx-code-editor {
  font-size: 14px;
  border: 1px solid #ddd;
  line-height: 150%;
}

.jcx-code-editor:deep(.CodeMirror) {
  height: 100%;
}

.CodeMirror-hints {
  z-index: 3000 !important;
}

.CodeMirror-lint-tooltip {
  z-index: 3000 !important;
}
</style>
